package com.jiangyg.mall.sentinel;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.jiangyg.mall.core.support.restful.Result;
import com.jiangyg.mall.core.utils.Logger;
import com.jiangyg.mall.core.utils.WebUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 类描述：SERVLET 服务的 Sentinel 配置
 *
 * @author jiangyg
 * @date 2022-09-17
 */
@Slf4j
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnProperty(name = "spring.cloud.sentinel.enabled", matchIfMissing = true)
public class SentinelWebAutoConfiguration {

    /**
     * 功能描述：限流异常处理
     *
     * @return BlockExceptionHandler 异常处理
     */
    @Bean
    public BlockExceptionHandler blockExceptionHandler() {
        return (request, response, ex) -> {
            if (ex instanceof FlowException) {
                WebUtils.out(response, Result.instance("461"));
            } else if (ex instanceof DegradeException) {
                WebUtils.out(response, Result.instance("462"));
            } else if (ex instanceof ParamFlowException) {
                WebUtils.out(response, Result.instance("463"));
            } else if (ex instanceof SystemBlockException) {
                WebUtils.out(response, Result.instance("464"));
            } else if (ex instanceof AuthorityException) {
                WebUtils.out(response, Result.instance("465"));
            } else {
                Logger.error(log, () -> String.format("请求[%s]触发未知限流规则", WebUtils.getRequestPath(request)), ex);
                WebUtils.out(response, Result.instance("466"));
            }
        };
    }

}
